home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / shutdown.lzh / shutdown_5.1 / src / shutdown_lib / shutdown_library.c < prev    next >
C/C++ Source or Header  |  1996-12-02  |  5KB  |  207 lines

  1. /*
  2.    shutdown_library.c --- simple shutdown library
  3.  
  4.    This library is compatible with the shutdown library
  5.    written by Olaf Barthel (AmiNet:util/boot/Shutdown2_0.lha).
  6.    It is _NOT_ an update but a twin which is reduced to
  7.    calling the hook functions. You can use the library of your
  8.    preference. An update to the original library will be
  9.    released later (see IDEAS, more ideas are welcome).
  10.  
  11.    This module is based on code from the original library
  12.    Copyright © 1992 by Olaf `Olsen' Barthel (not for commercial use)
  13.  
  14.    Written by Bernhard Fastenrath (fasten@shw.com)
  15. */
  16.  
  17. #include <exec/types.h>
  18. #include <exec/memory.h>
  19. #include <exec/semaphores.h>
  20. #include <utility/hooks.h>
  21. #include <proto/exec.h>
  22. #include <string.h>
  23.  
  24. #if defined (__GNUC__)
  25. #include <stabs.h>
  26. #endif
  27.  
  28. #include "shutdownbase.h"
  29.  
  30. typedef struct Hook Hook;
  31. typedef struct TagItem TagItem;
  32. typedef struct MinList MinList;
  33. typedef struct Node Node;
  34. typedef struct SignalSemaphore SignalSemaphore;
  35.  
  36. struct ExecBase *SysBase;
  37. struct DosLibrary *DOSBase = NULL;
  38. struct Library *UtilityBase = NULL;
  39. struct Library *ShutdownBase;
  40.  
  41. MinList ShutdownList;
  42. SignalSemaphore AccessLock;
  43. SignalSemaphore    ShutdownLock;
  44. BYTE Closing = 0;
  45.  
  46. #if defined (__GNUC__)
  47. const BYTE LibName[] = "shutdown.library";
  48. const BYTE LibIdString[] = "$VER: shutdown.library 2.3 (10-26-95)";
  49. const UWORD LibVersion = 2;
  50. const UWORD LibRevision = 3;
  51. #endif
  52.  
  53. #if defined (__GNUC__)
  54. #define LIBRT
  55. #define REG(regname)
  56. #define STRUCT_MYLIB struct Library
  57. #elif defined (__SASC_60)
  58. #define LIBRT __saveds __asm
  59. #define REG(regname) register __ ## regname
  60. #define ADDTABL_1(name,arg1);
  61. #define ADDTABL_2(name,arg1,arg2);
  62. #define ADDTABL_3(name,arg1,arg2,arg3);
  63. #define ADDTABL_END();
  64. #define STRUCT_MYLIB struct MyLibrary
  65. #endif
  66.  
  67. /*** internal functions ***/
  68.  
  69. static void
  70. CallClientHooks (void)
  71. {
  72.   if (ShutdownList.mlh_Head -> mln_Succ)
  73.   {
  74.     ShutdownInfo *Info, *NextInfo;
  75.     ULONG Mode;
  76.  
  77.     Info = (ShutdownInfo *) ShutdownList.mlh_Head;
  78.     while (NextInfo = (ShutdownInfo *) Info -> sdi_Node.mln_Succ)
  79.     {
  80.       Mode = SD_EXIT;
  81.       CallHook (Info -> sdi_Hook, &Mode, NULL);
  82.       Info = NextInfo;
  83.     }
  84.   }
  85. }
  86.  
  87. static void
  88. cleanup (void)
  89. {
  90.   if (DOSBase)
  91.     CloseLibrary ((struct Library *) DOSBase);
  92.   DOSBase = NULL;
  93.   if (UtilityBase)
  94.     CloseLibrary ((struct Library *) UtilityBase);
  95.   UtilityBase = NULL;
  96. }
  97.  
  98. /*** library interface ***/
  99.  
  100. int LIBRT
  101. __UserLibInit (REG(a6) STRUCT_MYLIB *libbase)
  102. {
  103.   SysBase = *(struct ExecBase **)4;
  104.   ShutdownBase = (struct Library *) libbase;
  105.  
  106.   if (!(DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 37)))
  107.     return 1;
  108.   if (!(UtilityBase = OpenLibrary ("utility.library", 37)))
  109.   {
  110.     cleanup ();
  111.     return 1;
  112.   }
  113.   InitSemaphore(&AccessLock);
  114.   InitSemaphore(&ShutdownLock);
  115.   NewList ((struct List *) &ShutdownList);
  116.   return 0; /* success */
  117. }
  118.  
  119. void LIBRT
  120. __UserLibCleanup (REG(a6) STRUCT_MYLIB *libbase)
  121. {
  122.   cleanup ();
  123. }
  124.  
  125. ADDTABL_1(LIBRexxDispatch,a0);
  126.  
  127. LONG LIBRT
  128. LIBRexxDispatch (REG(a0) void *Message)
  129. {
  130.   return 0;
  131. }
  132.  
  133. ADDTABL_3(LIBAddShutdownInfoTagList,a0,a1,a2);
  134.  
  135. APTR LIBRT
  136. LIBAddShutdownInfoTagList (REG(a0) Hook *Hook, REG(a1) STRPTR Name, REG(a2) TagItem *TagList)
  137. {
  138.   if (!Closing)
  139.   {
  140.     if (Hook && Name && TagList)
  141.     {
  142.        ShutdownInfo *Info;
  143.        LONG Len = strlen (Name);
  144.  
  145.        if (Info = (ShutdownInfo *) AllocVec (sizeof (ShutdownInfo) + Len + 1, MEMF_PUBLIC | MEMF_CLEAR))
  146.        {
  147.          ObtainSemaphore (&AccessLock);
  148.          Info -> sdi_Hook = Hook;
  149.          Info -> sdi_Name = (STRPTR)(Info + 1);
  150.          strcpy (Info -> sdi_Name, Name);
  151.          AddTail ((struct List *) &ShutdownList, (struct Node *) Info);
  152.          ReleaseSemaphore (&AccessLock);
  153.          return Info;
  154.        }
  155.     }
  156.   }
  157.   return NULL;
  158. }
  159.  
  160. ADDTABL_1(LIBRemShutdownInfo,a0);
  161.  
  162. LONG LIBRT
  163. LIBRemShutdownInfo (REG(a0) ShutdownInfo *Info)
  164. {
  165.   if (!Closing && Info)
  166.   {
  167.      ShutdownInfo *node, *next;
  168.  
  169.      ObtainSemaphore (&AccessLock);
  170.      node = (ShutdownInfo *) ShutdownList.mlh_Head;
  171.      while (next = (ShutdownInfo *) node -> sdi_Node.mln_Succ)
  172.      {
  173.        if (Info == (ShutdownInfo *) node)
  174.        {
  175.          Remove ((struct Node *) Info);
  176.          FreeVec (Info);
  177.          ReleaseSemaphore (&AccessLock);
  178.          return TRUE;
  179.        }
  180.        node = next;
  181.      }
  182.      ReleaseSemaphore (&AccessLock);
  183.   }
  184.   return FALSE;
  185. }
  186.  
  187. ADDTABL_1(LIBShutdown,d0);
  188.  
  189. LONG LIBRT
  190. LIBShutdown (REG(d0) ULONG mode)
  191. {
  192.   if (!AttemptSemaphore (&ShutdownLock))
  193.     return FALSE;
  194.   else
  195.   {
  196.     /* mode is ignored by this library but
  197.        not by the original shutdown.libray */
  198.  
  199.     CallClientHooks ();
  200.     ReleaseSemaphore (&ShutdownLock);
  201.     return TRUE;
  202.   }
  203.   return FALSE;
  204. }
  205.  
  206. ADDTABL_END();
  207.